/**
 * 浏览器兼容性检测和降级方案模块
 * 检测浏览器功能支持情况并提供相应的降级方案
 * @module browserCompatibility
 */

/**
 * 浏览器信息接口
 * @interface
 */
export interface BrowserInfo {
  /** 浏览器名称 */
  name: string
  /** 浏览器版本 */
  version: string
  /** 是否为移动设备 */
  isMobile: boolean
  /** 操作系统 */
  os: string
}

/**
 * 功能支持检测结果接口
 * @interface
 */
export interface FeatureSupport {
  /** Canvas 2D API支持 */
  canvas2d: boolean
  /** Web Audio API支持 */
  webAudio: boolean
  /** LocalStorage支持 */
  localStorage: boolean
  /** RequestAnimationFrame支持 */
  requestAnimationFrame: boolean
  /** CSS3动画支持 */
  css3Animations: boolean
  /** Touch事件支持 */
  touchEvents: boolean
  /** WebGL支持 */
  webgl: boolean
  /** ES6支持 */
  es6: boolean
  /** Intersection Observer支持 */
  intersectionObserver: boolean
  /** Resize Observer支持 */
  resizeObserver: boolean
}

/**
 * 兼容性报告接口
 * @interface
 */
export interface CompatibilityReport {
  /** 浏览器信息 */
  browser: BrowserInfo
  /** 功能支持情况 */
  features: FeatureSupport
  /** 兼容性等级 */
  compatibilityLevel: 'excellent' | 'good' | 'fair' | 'poor'
  /** 警告信息 */
  warnings: string[]
  /** 建议信息 */
  recommendations: string[]
}

/**
 * 浏览器兼容性管理类
 * 提供浏览器检测、功能测试和降级方案
 * @class
 */
class BrowserCompatibility {
  private cachedBrowserInfo: BrowserInfo | null = null
  private cachedFeatureSupport: FeatureSupport | null = null
  private fallbacksApplied: Set<string> = new Set()

  /**
   * 检测浏览器信息
   * @returns 浏览器信息对象
   * @example
   * const browserInfo = browserCompatibility.detectBrowser();
   * console.log(`浏览器: ${browserInfo.name} ${browserInfo.version}`);
   */
  detectBrowser(): BrowserInfo {
    if (this.cachedBrowserInfo) {
      return this.cachedBrowserInfo
    }

    const userAgent = navigator.userAgent
    let name = 'Unknown'
    let version = 'Unknown'
    let os = 'Unknown'

    // 检测浏览器名称和版本
    if (userAgent.includes('Chrome') && !userAgent.includes('Edg')) {
      name = 'Chrome'
      const match = userAgent.match(/Chrome\/(\d+)/)
      version = match ? match[1] : 'Unknown'
    } else if (userAgent.includes('Firefox')) {
      name = 'Firefox'
      const match = userAgent.match(/Firefox\/(\d+)/)
      version = match ? match[1] : 'Unknown'
    } else if (userAgent.includes('Safari') && !userAgent.includes('Chrome')) {
      name = 'Safari'
      const match = userAgent.match(/Version\/(\d+)/)
      version = match ? match[1] : 'Unknown'
    } else if (userAgent.includes('Edg')) {
      name = 'Edge'
      const match = userAgent.match(/Edg\/(\d+)/)
      version = match ? match[1] : 'Unknown'
    } else if (userAgent.includes('MSIE') || userAgent.includes('Trident')) {
      name = 'Internet Explorer'
      const match = userAgent.match(/(?:MSIE |rv:)(\d+)/)
      version = match ? match[1] : 'Unknown'
    }

    // 检测操作系统
    if (userAgent.includes('Windows')) {
      os = 'Windows'
    } else if (userAgent.includes('Android')) {
      os = 'Android'
    } else if (userAgent.includes('iPhone') || userAgent.includes('iPad') || userAgent.includes('iPod')) {
      os = 'iOS'
    } else if (userAgent.includes('Mac')) {
      os = 'macOS'
    } else if (userAgent.includes('Linux')) {
      os = 'Linux'
    }

    // 检测是否为移动设备
    const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent)

    this.cachedBrowserInfo = { name, version, isMobile, os }
    return this.cachedBrowserInfo
  }

  /**
   * 检测功能支持情况
   * @returns 功能支持检测结果
   * @example
   * const features = browserCompatibility.detectFeatureSupport();
   * if (!features.webAudio) {
   *   console.log('浏览器不支持Web Audio API');
   * }
   */
  detectFeatureSupport(): FeatureSupport {
    if (this.cachedFeatureSupport) {
      return this.cachedFeatureSupport
    }

    const features: FeatureSupport = {
      canvas2d: this.testCanvas2D(),
      webAudio: this.testWebAudio(),
      localStorage: this.testLocalStorage(),
      requestAnimationFrame: this.testRequestAnimationFrame(),
      css3Animations: this.testCSS3Animations(),
      touchEvents: this.testTouchEvents(),
      webgl: this.testWebGL(),
      es6: this.testES6(),
      intersectionObserver: this.testIntersectionObserver(),
      resizeObserver: this.testResizeObserver()
    }

    this.cachedFeatureSupport = features
    return features
  }

  /**
   * 生成完整的兼容性报告
   * @returns 兼容性报告对象
   * @example
   * const report = browserCompatibility.generateCompatibilityReport();
   * console.log(`兼容性等级: ${report.compatibilityLevel}`);
   */
  generateCompatibilityReport(): CompatibilityReport {
    const browser = this.detectBrowser()
    const features = this.detectFeatureSupport()
    
    // 计算兼容性等级
    const supportedFeatures = Object.values(features).filter(Boolean).length
    const totalFeatures = Object.keys(features).length
    const supportRatio = supportedFeatures / totalFeatures

    let compatibilityLevel: CompatibilityReport['compatibilityLevel']
    if (supportRatio >= 0.9) {
      compatibilityLevel = 'excellent'
    } else if (supportRatio >= 0.7) {
      compatibilityLevel = 'good'
    } else if (supportRatio >= 0.5) {
      compatibilityLevel = 'fair'
    } else {
      compatibilityLevel = 'poor'
    }

    // 生成警告和建议
    const warnings: string[] = []
    const recommendations: string[] = []

    if (!features.canvas2d) {
      warnings.push('浏览器不支持Canvas 2D API，游戏渲染可能出现问题')
      recommendations.push('请升级到支持Canvas的现代浏览器')
    }

    if (!features.webAudio) {
      warnings.push('浏览器不支持Web Audio API，游戏将无声音')
      recommendations.push('建议使用Chrome、Firefox或Safari的最新版本')
    }

    if (!features.localStorage) {
      warnings.push('浏览器不支持LocalStorage，游戏进度无法保存')
      recommendations.push('请检查浏览器隐私设置或使用现代浏览器')
    }

    if (!features.requestAnimationFrame) {
      warnings.push('浏览器不支持RequestAnimationFrame，游戏性能可能较差')
      recommendations.push('建议升级浏览器以获得更好的性能')
    }

    if (browser.name === 'Internet Explorer') {
      warnings.push('Internet Explorer浏览器兼容性较差')
      recommendations.push('强烈建议使用Chrome、Firefox、Safari或Edge浏览器')
    }

    if (parseInt(browser.version) < 60 && browser.name === 'Chrome') {
      warnings.push('Chrome版本过低，可能存在兼容性问题')
      recommendations.push('请升级到Chrome 90或更高版本')
    }

    return {
      browser,
      features,
      compatibilityLevel,
      warnings,
      recommendations
    }
  }

  /**
   * 应用Canvas渲染降级方案
   * 当Canvas不可用时使用CSS渲染
   * @returns 是否成功应用降级方案
   */
  applyCanvasFallback(): boolean {
    if (this.fallbacksApplied.has('canvas')) {
      return true
    }

    try {
      // 添加CSS类来启用CSS渲染模式
      document.documentElement.classList.add('canvas-fallback')
      
      // 创建样式规则
      const style = document.createElement('style')
      style.textContent = `
        .canvas-fallback .game-canvas {
          display: none;
        }
        .canvas-fallback .css-renderer {
          display: block;
          position: relative;
          width: 100%;
          height: 400px;
          background: linear-gradient(to bottom, #87CEEB, #98FB98);
          overflow: hidden;
        }
        .canvas-fallback .game-entity {
          position: absolute;
          transition: transform 0.1s ease-out;
        }
        .canvas-fallback .player {
          width: 40px;
          height: 60px;
          background: #FF6B6B;
          border-radius: 8px;
          bottom: 0;
          left: 100px;
        }
        .canvas-fallback .obstacle {
          width: 30px;
          height: 50px;
          background: #4ECDC4;
          border-radius: 4px;
          bottom: 0;
        }
      `
      document.head.appendChild(style)
      
      this.fallbacksApplied.add('canvas')
      console.log('Canvas降级方案已应用')
      return true
    } catch (error) {
      console.error('应用Canvas降级方案失败:', error)
      return false
    }
  }

  /**
   * 应用音频降级方案
   * 当Web Audio API不可用时禁用音频功能
   * @returns 是否成功应用降级方案
   */
  applyAudioFallback(): boolean {
    if (this.fallbacksApplied.has('audio')) {
      return true
    }

    try {
      // 设置全局音频禁用标志
      (window as any).__AUDIO_DISABLED__ = true
      
      // 添加视觉提示
      document.documentElement.classList.add('audio-disabled')
      
      this.fallbacksApplied.add('audio')
      console.log('音频降级方案已应用')
      return true
    } catch (error) {
      console.error('应用音频降级方案失败:', error)
      return false
    }
  }

  /**
   * 应用动画降级方案
   * 当CSS3动画不支持时使用简化动画
   * @returns 是否成功应用降级方案
   */
  applyAnimationFallback(): boolean {
    if (this.fallbacksApplied.has('animation')) {
      return true
    }

    try {
      document.documentElement.classList.add('animation-fallback')
      
      const style = document.createElement('style')
      style.textContent = `
        .animation-fallback * {
          animation: none !important;
          transition: none !important;
        }
        .animation-fallback .simple-fade {
          opacity: 0.8;
        }
        .animation-fallback .simple-move {
          transform: translateX(10px);
        }
      `
      document.head.appendChild(style)
      
      this.fallbacksApplied.add('animation')
      console.log('动画降级方案已应用')
      return true
    } catch (error) {
      console.error('应用动画降级方案失败:', error)
      return false
    }
  }

  /**
   * 应用存储降级方案
   * 当LocalStorage不可用时使用内存存储
   * @returns 是否成功应用降级方案
   */
  applyStorageFallback(): boolean {
    if (this.fallbacksApplied.has('storage')) {
      return true
    }

    try {
      // 内存存储已在polyfills中实现
      (window as any).__STORAGE_FALLBACK__ = true
      
      this.fallbacksApplied.add('storage')
      console.log('存储降级方案已应用')
      return true
    } catch (error) {
      console.error('应用存储降级方案失败:', error)
      return false
    }
  }

  /**
   * 应用所有必要的降级方案
   * 根据浏览器功能支持情况自动应用相应的降级方案
   * @example
   * browserCompatibility.applyAllFallbacks();
   */
  applyAllFallbacks(): void {
    const features = this.detectFeatureSupport()
    
    if (!features.canvas2d) {
      this.applyCanvasFallback()
    }
    
    if (!features.webAudio) {
      this.applyAudioFallback()
    }
    
    if (!features.css3Animations) {
      this.applyAnimationFallback()
    }
    
    if (!features.localStorage) {
      this.applyStorageFallback()
    }
  }

  /**
   * 检查是否需要显示兼容性警告
   * @returns 是否需要显示警告
   */
  shouldShowCompatibilityWarning(): boolean {
    const report = this.generateCompatibilityReport()
    return report.compatibilityLevel === 'poor' || report.warnings.length > 2
  }

  /**
   * 获取兼容性警告消息
   * @returns 警告消息字符串
   */
  getCompatibilityWarningMessage(): string {
    const report = this.generateCompatibilityReport()
    const browser = report.browser
    
    if (browser.name === 'Internet Explorer') {
      return `您正在使用Internet Explorer浏览器，该浏览器不支持现代Web技术。为了获得最佳游戏体验，请使用Chrome、Firefox、Safari或Edge浏览器。`
    }
    
    if (report.compatibilityLevel === 'poor') {
      return `您的浏览器兼容性较差，游戏可能无法正常运行。建议升级到最新版本的现代浏览器。`
    }
    
    if (report.warnings.length > 0) {
      return `检测到以下兼容性问题：${report.warnings.join('；')}。建议升级浏览器以获得更好的体验。`
    }
    
    return ''
  }

  // 私有测试方法
  private testCanvas2D(): boolean {
    try {
      const canvas = document.createElement('canvas')
      if (!canvas.getContext) {
        return false
      }
      const context = canvas.getContext('2d')
      return !!context
    } catch {
      return false
    }
  }

  private testWebAudio(): boolean {
    return !!(window.AudioContext || (window as any).webkitAudioContext)
  }

  private testLocalStorage(): boolean {
    try {
      const test = '__localStorage_test__'
      localStorage.setItem(test, test)
      localStorage.removeItem(test)
      return true
    } catch {
      return false
    }
  }

  private testRequestAnimationFrame(): boolean {
    return !!(window.requestAnimationFrame || (window as any).webkitRequestAnimationFrame)
  }

  private testCSS3Animations(): boolean {
    const element = document.createElement('div')
    const properties = ['animation', 'webkitAnimation', 'mozAnimation', 'oAnimation', 'msAnimation']
    return properties.some(prop => prop in element.style)
  }

  private testTouchEvents(): boolean {
    return 'ontouchstart' in window || navigator.maxTouchPoints > 0
  }

  private testWebGL(): boolean {
    try {
      const canvas = document.createElement('canvas')
      return !!(canvas.getContext('webgl') || canvas.getContext('experimental-webgl'))
    } catch {
      return false
    }
  }

  private testES6(): boolean {
    try {
      // 测试箭头函数、const/let、模板字符串等ES6特性
      // 使用 Function 构造函数替代 eval，更安全
      const testFunction = new Function('return (() => `ES6 supported`)()')
      testFunction()
      return true
    } catch {
      return false
    }
  }

  private testIntersectionObserver(): boolean {
    return 'IntersectionObserver' in window
  }

  private testResizeObserver(): boolean {
    return 'ResizeObserver' in window
  }
}

/**
 * 浏览器兼容性管理器单例实例
 * 全局唯一的兼容性管理实例
 * @example
 * import { browserCompatibility } from '@/utils/browserCompatibility';
 * const report = browserCompatibility.generateCompatibilityReport();
 */
export const browserCompatibility = new BrowserCompatibility()